﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义最大用户数和最大机票数（可根据实际情况调整）
#define MAX_USERS 100
#define MAX_TICKETS 100

// 定义用户类型标识
#define USER_TYPE_USER 1
#define USER_TYPE_ADMIN 2

// 定义机票结构体
typedef struct Ticket {
    int num;
    char city[50];
    char time[50];
    int price;
    int discount;
    int capacity;
} Ticket;

// 定义用户结构体
typedef struct User {
    char name[100];
    int password;
    int bookedTicket;
    int userType;  // 1表示普通用户，2表示管理员
} User;

// 全局变量，记录机票数量和用户数量
int ticketCount = 0;
int userCount = 0;
Ticket tickets[MAX_TICKETS];
User users[MAX_USERS];

// 文件名宏定义（假设数据存储在这个文件中，可根据实际调整）
#define FILENAME "ticket_data.txt"
// 函数声明部分

// 加载机票信息
void loadTickets();

// 保存机票信息
void saveTickets();

// 注册用户
void registerUser();

// 登录函数，区分用户和管理员登录
void login();

// 用户菜单
void userMenu();

// 管理员菜单
void adminMenu();

// 添加航班
void addTicket();

// 折半查找航班
int binarySearchTicket(int ticketNum);

// 查找航班
void findTicket();

// 订票
void buyTicket();

// 退票
void refundTicket();

// 修改航班
void modifyTicket();

// 删除航班
void deleteTicket();
// 加载机票信息
void loadTickets() {
    FILE* file = fopen(FILENAME, "r");
    if (file == NULL) {
        printf("机票数据文件不存在，初始化为空。\n");
        return;
    }

    while (fscanf(file, "%d %s %s %d %d %d", &tickets[ticketCount].num,
        tickets[ticketCount].city, tickets[ticketCount].time,
        &tickets[ticketCount].price, &tickets[ticketCount].discount,
        &tickets[ticketCount].capacity) != EOF) {
        ticketCount++;
    }
    fclose(file);
}

// 保存机票信息
void saveTickets() {
    FILE* file = fopen(FILENAME, "w");
    if (file == NULL) {
        printf("无法保存机票数据！\n");
        return;
    }

    for (int i = 0; i < ticketCount; i++) {
        fprintf(file, "%d %s %s %d %d %d\n", tickets[i].num, tickets[i].city,
            tickets[i].time, tickets[i].price, tickets[i].discount,
            tickets[i].capacity);
    }
    fclose(file);
}

// 注册用户
void registerUser() {
    if (userCount >= MAX_USERS) {
        printf("无法注册更多用户，已达最大容量。\n");
        return;
    }

    User newUser;
    printf("请输入用户名: ");
    scanf("%s", newUser.name);
    // 简单验证密码长度，可进一步完善验证逻辑
    do {
        printf("请输入密码（建议为数字，长度大于0）: ");
        scanf("%d", &newUser.password);
        if (newUser.password <= 0) {
            printf("密码不符合要求，请重新输入。\n");
        }
    } while (newUser.password <= 0);

    printf("请选择用户类型（1表示普通用户，2表示管理员）: ");
    scanf("%d", &newUser.userType);
    newUser.bookedTicket = -1;

    users[userCount++] = newUser;
    printf("注册成功！\n");
}

// 登录函数，区分用户和管理员登录
void login() {
    char name[100];
    int password;
    printf("请输入用户名: ");
    scanf("%s", name);
    printf("请输入密码: ");
    scanf("%d", &password);

    for (int i = 0; i < userCount; i++) {
        if (strcmp(users[i].name, name) == 0 && users[i].password == password) {
            if (users[i].userType == USER_TYPE_USER) {
                printf("用户登录成功！\n");
                userMenu();
            }
            else if (users[i].userType == USER_TYPE_ADMIN) {
                printf("管理员登录成功！\n");
                adminMenu();
            }
            return;
        }
    }
    printf("用户名或密码错误。\n");
}

// 用户菜单
void userMenu() {
    int choice;
    while (1) {
        printf("\n===== 用户操作菜单 =====\n");
        printf("1. 订票\n");
        printf("2. 退票\n");
        printf("3. 返回上一级\n");
        printf("请选择操作: ");
        scanf("%d", &choice);

        switch (choice) {
        case 1:
            buyTicket();
            break;
        case 2:
            refundTicket();
            break;
        case 3:
            return;
        default:
            printf("无效的选项，请重试。\n");
        }
    }
}

// 管理员菜单
void adminMenu() {
    int choice;
    while (1) {
        printf("\n===== 管理员操作菜单 =====\n");
        printf("1. 添加航班\n");
        printf("2. 修改航班\n");
        printf("3. 查找航班\n");
        printf("4. 删除航班\n");
        printf("5. 返回上一级\n");
        printf("请选择操作: ");
        scanf("%d", &choice);

        switch (choice) {
        case 1:
            addTicket();
            break;
        case 2:
            modifyTicket();
            break;
        case 3:
            findTicket();
            break;
        case 4:
            deleteTicket();
            break;
        case 5:
            return;
        default:
            printf("无效的选项，请重试。\n");
        }
    }
}

// 添加航班
void addTicket() {
    if (ticketCount >= MAX_TICKETS) {
        printf("无法添加更多航班，已达最大容量。\n");
        return;
    }

    Ticket newTicket;
    printf("请输入票号: ");
    scanf("%d", &newTicket.num);
    printf("请输入城市: ");
    scanf("%s", newTicket.city);
    printf("请输入起飞时间: ");
    scanf("%s", newTicket.time);
    printf("请输入票价: ");
    scanf("%d", &newTicket.price);
    printf("请输入折扣: ");
    scanf("%d", &newTicket.discount);
    printf("请输入容量: ");
    scanf("%d", &newTicket.capacity);

    tickets[ticketCount++] = newTicket;
    printf("航班添加成功！\n");
}

// 折半查找航班
int binarySearchTicket(int ticketNum) {
    int left = 0, right = ticketCount - 1;

    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (tickets[mid].num == ticketNum) {
            return mid;
        }
        else if (tickets[mid].num < ticketNum) {
            left = mid + 1;
        }
        else {
            right = mid - 1;
        }
    }
    return -1; // 未找到
}

// 查找航班
void findTicket() {
    int ticketNum;
    printf("请输入要查找的票号: ");
    scanf("%d", &ticketNum);

    int index = binarySearchTicket(ticketNum);
    if (index != -1) {
        printf("票号: %d\n", tickets[index].num);
        printf("城市: %s\n", tickets[index].city);
        printf("起飞时间: %s\n", tickets[index].time);
        printf("票价: %d\n", tickets[index].price);
        printf("折扣: %d\n", tickets[index].discount);
        printf("容量: %d\n", tickets[index].capacity);
    }
    else {
        printf("未找到该票号的航班。\n");
    }
}

// 订票
void buyTicket() {
    char name[100];
    int ticketNum;

    printf("请输入用户名: ");
    scanf("%s", name);

    int userIndex = -1;
    for (int i = 0; i < userCount; i++) {
        if (strcmp(users[i].name, name) == 0) {
            userIndex = i;
            break;
        }
    }

    if (userIndex == -1) {
        printf("用户不存在。\n");
        return;
    }

    printf("请输入票号: ");
    scanf("%d", &ticketNum);

    int ticketIndex = binarySearchTicket(ticketNum);
    if (ticketIndex == -1) {
        printf("未找到该票号的航班。\n");
        return;
    }

    if (tickets[ticketIndex].capacity > 0) {
        tickets[ticketIndex].capacity--;
        users[userIndex].bookedTicket = ticketNum;
        printf("订票成功！\n");
    }
    else {
        printf("该航班已无余票。\n");
    }
}

// 退票
void refundTicket() {
    char name[100];
    printf("请输入用户名: ");
    scanf("%s", name);

    int userIndex = -1;
    for (int i = 0; i < userCount; i++) {
        if (strcmp(users[i].name, name) == 0) {
            userIndex = i;
            break;
        }
    }

    if (userIndex == -1 || users[userIndex].bookedTicket == -1) {
        printf("用户未订票或不存在。\n");
        return;
    }

    int ticketIndex = binarySearchTicket(users[userIndex].bookedTicket);
    tickets[ticketIndex].capacity++;
    users[userIndex].bookedTicket = -1;
    printf("退票成功！\n");
}

// 修改航班
void modifyTicket() {
    int ticketNum;
    printf("请输入要修改的航班票号: ");
    scanf("%d", &ticketNum);

    int index = binarySearchTicket(ticketNum);
    if (index == -1) {
        printf("未找到该票号的航班。\n");
        return;
    }

    printf("修改航班信息（输入新值，保持不变则输入原值）：\n");
    printf("当前城市: %s，新城市: ", tickets[index].city);
    scanf("%s", tickets[index].city);
    printf("当前起飞时间: %s，新时间: ", tickets[index].time);
    scanf("%s", tickets[index].time);
    printf("当前票价: %d，新票价: ", tickets[index].price);
    scanf("%d", &tickets[index].price);
    printf("当前折扣: %d，新折扣: ", tickets[index].discount);
    scanf("%d", &tickets[index].discount);
    printf("当前容量: %d，新容量: ", tickets[index].capacity);
    scanf("%d", &tickets[index].capacity);

    printf("航班信息修改成功！\n");
}

// 删除航班
void deleteTicket() {
    int ticketNum;
    printf("要输入要删除的航班票号: ");
    scanf("%d", &ticketNum);

    int index = binarySearchTicket(ticketNum);
    if (index == -1) {
        printf("未找到要删除的票号对应的航班，无法删除。\n");
        return;
    }

    // 将后面的元素依次向前移动覆盖要删除的元素
    for (int i = index; i < ticketCount - 1; i++) {
        tickets[i] = tickets[i + 1];
    }
    ticketCount--;
    printf("航班删除成功！\n");
}

int main() {
    int choice;
    loadTickets(); // 从文件加载机票信息

    while (1) {
        printf("\n===== 飞机订票系统 =====\n");
        printf("1. 注册\n");
        printf("2. 登录\n");
        printf("3. 退出\n");
        printf("请选择操作: ");
        scanf("%d", &choice);

        switch (choice) {
        case 1:
            registerUser();
            break;
        case 2:
            login();
            break;
        case 3:
            saveTickets();
            exit(0);
        default:
            printf("无效的选项，请重试。\n");
        }
    }

    return 0;
}